<template>
  <div class="max-w-4xl mx-auto p-4">
    <a-card>
      <a-typography-title :level="2">图片处理工具</a-typography-title>
      
      <a-form layout="vertical">
        <!-- 图片上传区域 -->
        <a-form-item>
          <a-upload-dragger
            v-model:fileList="fileList"
            :beforeUpload="handleBeforeUpload"
            :showUploadList="false"
            accept="image/*"
          >
            <p class="ant-upload-drag-icon">
              <component :is="fileUrl ? 'img' : 'inbox-outlined'" 
                :src="fileUrl" 
                :style="fileUrl ? 'max-width: 100%; max-height: 300px;' : ''"
              />
            </p>
            <p class="ant-upload-text">点击或拖拽图片到此区域</p>
            <p class="ant-upload-hint">
              支持单个或批量上传，每个文件不超过 10MB
            </p>
          </a-upload-dragger>
        </a-form-item>

        <template v-if="fileUrl">
          <!-- 图片信息 -->
          <a-descriptions :column="2" size="small" class="mb-4">
            <a-descriptions-item label="尺寸">{{ imageInfo.width }} x {{ imageInfo.height }}</a-descriptions-item>
            <a-descriptions-item label="大小">{{ formatFileSize(imageInfo.size) }}</a-descriptions-item>
            <a-descriptions-item label="类型">{{ imageInfo.type }}</a-descriptions-item>
            <a-descriptions-item label="名称">{{ imageInfo.name }}</a-descriptions-item>
          </a-descriptions>

          <!-- 操作选项 -->
          <a-tabs v-model:activeKey="activeTab">
            <!-- 格式转换 -->
            <a-tab-pane key="format" tab="格式转换">
              <a-form-item label="目标格式">
                <a-radio-group v-model:value="formatOptions.targetFormat" button-style="solid">
                  <a-radio-button value="image/png">PNG</a-radio-button>
                  <a-radio-button value="image/jpeg">JPEG</a-radio-button>
                  <a-radio-button value="image/webp">WebP</a-radio-button>
                </a-radio-group>
              </a-form-item>
              <a-form-item v-if="formatOptions.targetFormat === 'image/jpeg'" label="JPEG 质量">
                <a-slider
                  v-model:value="formatOptions.quality"
                  :min="0"
                  :max="100"
                  :step="1"
                />
              </a-form-item>
            </a-tab-pane>

            <!-- 尺寸调整 -->
            <a-tab-pane key="resize" tab="尺寸调整">
              <a-form-item label="调整方式">
                <a-radio-group v-model:value="resizeOptions.mode" button-style="solid">
                  <a-radio-button value="percentage">按百分比</a-radio-button>
                  <a-radio-button value="pixel">指定像素</a-radio-button>
                </a-radio-group>
              </a-form-item>
              
              <template v-if="resizeOptions.mode === 'percentage'">
                <a-form-item label="缩放比例">
                  <a-input-number
                    v-model:value="resizeOptions.percentage"
                    :min="1"
                    :max="200"
                    addon-after="%"
                    style="width: 160px"
                  />
                </a-form-item>
              </template>
              
              <template v-else>
                <a-row :gutter="16">
                  <a-col :span="12">
                    <a-form-item label="宽度">
                      <a-input-number
                        v-model:value="resizeOptions.width"
                        :min="1"
                        addon-after="px"
                        style="width: 160px"
                      />
                    </a-form-item>
                  </a-col>
                  <a-col :span="12">
                    <a-form-item label="高度">
                      <a-input-number
                        v-model:value="resizeOptions.height"
                        :min="1"
                        addon-after="px"
                        style="width: 160px"
                      />
                    </a-form-item>
                  </a-col>
                </a-row>
                <a-form-item>
                  <a-checkbox v-model:checked="resizeOptions.maintainAspectRatio">
                    保持宽高比
                  </a-checkbox>
                </a-form-item>
              </template>
            </a-tab-pane>

            <!-- 旋转/翻转 -->
            <a-tab-pane key="rotate" tab="旋转/翻转">
              <a-form-item label="旋转角度">
                <a-radio-group v-model:value="transformOptions.rotation" button-style="solid">
                  <a-radio-button value="0">0°</a-radio-button>
                  <a-radio-button value="90">90°</a-radio-button>
                  <a-radio-button value="180">180°</a-radio-button>
                  <a-radio-button value="270">270°</a-radio-button>
                </a-radio-group>
              </a-form-item>
              <a-form-item label="翻转">
                <a-space>
                  <a-checkbox v-model:checked="transformOptions.flipHorizontal">
                    水平翻转
                  </a-checkbox>
                  <a-checkbox v-model:checked="transformOptions.flipVertical">
                    垂直翻转
                  </a-checkbox>
                </a-space>
              </a-form-item>
            </a-tab-pane>

            <!-- 滤镜效果 -->
            <a-tab-pane key="filter" tab="滤镜效果">
              <a-form-item label="亮度">
                <a-slider
                  v-model:value="filterOptions.brightness"
                  :min="0"
                  :max="200"
                  :step="1"
                />
              </a-form-item>
              <a-form-item label="对比度">
                <a-slider
                  v-model:value="filterOptions.contrast"
                  :min="0"
                  :max="200"
                  :step="1"
                />
              </a-form-item>
              <a-form-item label="饱和度">
                <a-slider
                  v-model:value="filterOptions.saturation"
                  :min="0"
                  :max="200"
                  :step="1"
                />
              </a-form-item>
              <a-form-item label="模糊">
                <a-slider
                  v-model:value="filterOptions.blur"
                  :min="0"
                  :max="20"
                  :step="0.1"
                />
              </a-form-item>
            </a-tab-pane>

            <!-- 水印添加 -->
            <a-tab-pane key="watermark" tab="水印添加">
              <a-form-item label="水印类型">
                <a-radio-group v-model:value="watermarkOptions.type" button-style="solid">
                  <a-radio-button value="text">文字水印</a-radio-button>
                  <a-radio-button value="image">图片水印</a-radio-button>
                </a-radio-group>
              </a-form-item>

              <template v-if="watermarkOptions.type === 'text'">
                <a-form-item label="水印文字">
                  <a-input v-model:value="watermarkOptions.text" />
                </a-form-item>
                <a-form-item label="字体大小">
                  <a-input-number
                    v-model:value="watermarkOptions.fontSize"
                    :min="12"
                    :max="72"
                    addon-after="px"
                  />
                </a-form-item>
                <a-form-item label="文字颜色">
                  <a-input v-model:value="watermarkOptions.color" type="color" />
                </a-form-item>
              </template>

              <template v-else>
                <a-form-item label="水印图片">
                  <a-upload
                    v-model:fileList="watermarkFileList"
                    :beforeUpload="handleWatermarkUpload"
                    :maxCount="1"
                    accept="image/*"
                  >
                    <a-button>选择图片</a-button>
                  </a-upload>
                </a-form-item>
                <a-form-item label="不透明度">
                  <a-slider
                    v-model:value="watermarkOptions.opacity"
                    :min="0"
                    :max="100"
                    :step="1"
                  />
                </a-form-item>
              </template>

              <a-form-item label="位置">
                <a-select v-model:value="watermarkOptions.position">
                  <a-select-option value="top-left">左上角</a-select-option>
                  <a-select-option value="top-right">右上角</a-select-option>
                  <a-select-option value="bottom-left">左下角</a-select-option>
                  <a-select-option value="bottom-right">右下角</a-select-option>
                  <a-select-option value="center">居中</a-select-option>
                </a-select>
              </a-form-item>
            </a-tab-pane>
          </a-tabs>

          <!-- 操作按钮 -->
          <a-form-item>
            <a-space>
              <a-button type="primary" @click="processImage" :loading="processing">
                处理图片
              </a-button>
              <a-button @click="resetImage" :disabled="!hasChanges">
                重置
              </a-button>
              <a-button type="primary" @click="downloadImage" :disabled="!processedUrl">
                下载
              </a-button>
            </a-space>
          </a-form-item>
        </template>
      </a-form>
    </a-card>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed } from 'vue';
import { message } from 'ant-design-vue';
import { InboxOutlined } from '@ant-design/icons-vue';
import type { UploadProps } from 'ant-design-vue';

// 文件信息
const fileList = ref<any[]>([]);
const fileUrl = ref('');
const processedUrl = ref('');
const processing = ref(false);
const activeTab = ref('format');

// 图片信息
const imageInfo = reactive({
  width: 0,
  height: 0,
  size: 0,
  type: '',
  name: ''
});

// 格式转换选项
const formatOptions = reactive({
  targetFormat: 'image/png',
  quality: 90
});

// 尺寸调整选项
const resizeOptions = reactive({
  mode: 'percentage',
  percentage: 100,
  width: 800,
  height: 600,
  maintainAspectRatio: true
});

// 变换选项
const transformOptions = reactive({
  rotation: '0',
  flipHorizontal: false,
  flipVertical: false
});

// 滤镜选项
const filterOptions = reactive({
  brightness: 100,
  contrast: 100,
  saturation: 100,
  blur: 0
});

// 水印选项
const watermarkOptions = reactive({
  type: 'text',
  text: '水印文字',
  fontSize: 24,
  color: '#000000',
  opacity: 50,
  position: 'bottom-right',
  watermarkUrl: '' // 添加水印图片 URL
});

const watermarkFileList = ref<any[]>([]);

// 是否有更改
const hasChanges = computed(() => {
  return processedUrl.value !== fileUrl.value;
});

// 处理上传前的回调
const handleBeforeUpload: UploadProps['beforeUpload'] = (file) => {
  const isImage = file.type.startsWith('image/');
  if (!isImage) {
    message.error('只能上传图片文件！');
    return false;
  }

  const isLt10M = file.size / 1024 / 1024 < 10;
  if (!isLt10M) {
    message.error('图片必须小于 10MB！');
    return false;
  }

  // 读取图片信息
  const reader = new FileReader();
  reader.onload = (e) => {
    if (e.target?.result) {
      fileUrl.value = e.target.result as string;
      const img = new Image();
      img.onload = () => {
        imageInfo.width = img.width;
        imageInfo.height = img.height;
        imageInfo.size = file.size;
        imageInfo.type = file.type;
        imageInfo.name = file.name;
      };
      img.src = e.target.result as string;
    }
  };
  reader.readAsDataURL(file);

  return false;
};

// 处理水印图片上传
const handleWatermarkUpload: UploadProps['beforeUpload'] = (file) => {
  const isImage = file.type.startsWith('image/');
  if (!isImage) {
    message.error('只能上传图片文件！');
    return false;
  }

  const reader = new FileReader();
  reader.onload = (e) => {
    if (e.target?.result) {
      watermarkOptions.watermarkUrl = e.target.result as string;
    }
  };
  reader.readAsDataURL(file);

  return false;
};

// 处理图片
const processImage = async () => {
  if (!fileUrl.value) {
    message.warning('请先上传图片');
    return;
  }

  processing.value = true;
  try {
    const img = new Image();
    img.src = fileUrl.value;
    await new Promise((resolve) => {
      img.onload = resolve;
    });

    const canvas = document.createElement('canvas');
    let ctx = canvas.getContext('2d');
    if (!ctx) {
      throw new Error('无法创建 canvas 上下文');
    }

    // 应用变换
    let width = img.width;
    let height = img.height;

    // 处理尺寸调整
    if (activeTab.value === 'resize') {
      if (resizeOptions.mode === 'percentage') {
        width = (img.width * resizeOptions.percentage) / 100;
        height = (img.height * resizeOptions.percentage) / 100;
      } else {
        if (resizeOptions.maintainAspectRatio) {
          const ratio = img.width / img.height;
          if (resizeOptions.width) {
            width = resizeOptions.width;
            height = width / ratio;
          } else if (resizeOptions.height) {
            height = resizeOptions.height;
            width = height * ratio;
          }
        } else {
          width = resizeOptions.width || img.width;
          height = resizeOptions.height || img.height;
        }
      }
    }

    // 设置画布尺寸
    canvas.width = width;
    canvas.height = height;

    // 应用旋转和翻转
    if (activeTab.value === 'rotate') {
      const rotation = parseInt(transformOptions.rotation);
      if (rotation === 90 || rotation === 270) {
        canvas.width = height;
        canvas.height = width;
      }

      ctx.translate(canvas.width / 2, canvas.height / 2);
      ctx.rotate((rotation * Math.PI) / 180);
      ctx.translate(-width / 2, -height / 2);

      if (transformOptions.flipHorizontal) {
        ctx.scale(-1, 1);
        ctx.translate(-width, 0);
      }
      if (transformOptions.flipVertical) {
        ctx.scale(1, -1);
        ctx.translate(0, -height);
      }
    }

    // 绘制图片
    ctx.drawImage(img, 0, 0, width, height);

    // 应用滤镜
    if (activeTab.value === 'filter') {
      ctx.filter = `brightness(${filterOptions.brightness}%) contrast(${filterOptions.contrast}%) saturate(${filterOptions.saturation}%) blur(${filterOptions.blur}px)`;
      ctx.drawImage(canvas, 0, 0);
    }

    // 添加水印
    if (activeTab.value === 'watermark') {
      if (watermarkOptions.type === 'text') {
        ctx.font = `${watermarkOptions.fontSize}px Arial`;
        ctx.fillStyle = watermarkOptions.color;
        ctx.globalAlpha = watermarkOptions.opacity / 100;

        const text = watermarkOptions.text;
        const metrics = ctx.measureText(text);
        const textWidth = metrics.width;
        const textHeight = watermarkOptions.fontSize;

        let x = 0;
        let y = 0;

        switch (watermarkOptions.position) {
          case 'top-left':
            x = 10;
            y = textHeight + 10;
            break;
          case 'top-right':
            x = canvas.width - textWidth - 10;
            y = textHeight + 10;
            break;
          case 'bottom-left':
            x = 10;
            y = canvas.height - 10;
            break;
          case 'bottom-right':
            x = canvas.width - textWidth - 10;
            y = canvas.height - 10;
            break;
          case 'center':
            x = (canvas.width - textWidth) / 2;
            y = (canvas.height + textHeight) / 2;
            break;
        }

        ctx.fillText(text, x, y);
      } else if (watermarkOptions.watermarkUrl) {
        const watermarkImg = new Image();
        watermarkImg.src = watermarkOptions.watermarkUrl;
        await new Promise((resolve) => {
          watermarkImg.onload = resolve;
        });

        ctx.globalAlpha = watermarkOptions.opacity / 100;
        const maxSize = Math.min(canvas.width, canvas.height) / 4;
        const scale = Math.min(maxSize / watermarkImg.width, maxSize / watermarkImg.height);
        const wmWidth = watermarkImg.width * scale;
        const wmHeight = watermarkImg.height * scale;

        let x = 0;
        let y = 0;

        switch (watermarkOptions.position) {
          case 'top-left':
            x = 10;
            y = 10;
            break;
          case 'top-right':
            x = canvas.width - wmWidth - 10;
            y = 10;
            break;
          case 'bottom-left':
            x = 10;
            y = canvas.height - wmHeight - 10;
            break;
          case 'bottom-right':
            x = canvas.width - wmWidth - 10;
            y = canvas.height - wmHeight - 10;
            break;
          case 'center':
            x = (canvas.width - wmWidth) / 2;
            y = (canvas.height - wmHeight) / 2;
            break;
        }

        ctx.drawImage(watermarkImg, x, y, wmWidth, wmHeight);
      }
    }

    // 转换格式并输出
    const quality = formatOptions.targetFormat === 'image/jpeg' ? formatOptions.quality / 100 : undefined;
    processedUrl.value = canvas.toDataURL(formatOptions.targetFormat, quality);
    message.success('处理成功！');
  } catch (err) {
    message.error('处理失败：' + (err as Error).message);
    console.error('处理失败:', err);
  } finally {
    processing.value = false;
  }
};

// 重置图片
const resetImage = () => {
  processedUrl.value = fileUrl.value;
  message.success('已重置');
};

// 下载图片
const downloadImage = () => {
  if (!processedUrl.value) {
    message.warning('没有可下载的图片');
    return;
  }

  const link = document.createElement('a');
  link.download = `processed_${imageInfo.name}`;
  link.href = processedUrl.value;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
};

// 格式化文件大小
const formatFileSize = (bytes: number) => {
  if (bytes === 0) return '0 B';
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};
</script>

<style scoped>
.ant-card {
  background-color: white;
}

:deep(.ant-card-body) {
  padding: 24px;
}

:deep(.ant-upload-drag) {
  background: #fafafa;
}

:deep(.ant-tabs-nav) {
  margin-bottom: 24px;
}
</style> 